package com.bupt.vueblog.service.impl;

import com.bupt.vueblog.dao.BriefArticleDAO;
import com.bupt.vueblog.dao.DetailArticleDAO;
import com.bupt.vueblog.dao.RelationDAO;
import com.bupt.vueblog.domain.dto.ArticleInsertDTO;
import com.bupt.vueblog.domain.dto.ArticleSelectDTO;
import com.bupt.vueblog.domain.dto.ArticleUpdateDTO;
import com.bupt.vueblog.domain.dto.DetailInfoDTO;
import com.bupt.vueblog.domain.dto.ChangeNumDTO;
import com.bupt.vueblog.domain.entity.BriefArticle;
import com.bupt.vueblog.domain.entity.DetailArticle;
import com.bupt.vueblog.domain.entity.Relation;
import com.bupt.vueblog.domain.vo.AllArticleVO;
import com.bupt.vueblog.domain.vo.BriefArticleVO;
import com.bupt.vueblog.domain.vo.CommentVO;
import com.bupt.vueblog.domain.vo.DetailArticleVO;
import com.bupt.vueblog.service.ArticleService;
import com.bupt.vueblog.service.CommentService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author 谭继好
 * @Description
 * @date 2024-04-09 15:39
 */
@Service
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    private BriefArticleDAO briefArticleDAO;

    @Autowired
    private DetailArticleDAO detailArticleDAO;

    @Autowired
    private RelationDAO relationDAO;

    @Autowired
    private CommentService commentService;

    @Override
    // 查询所有博客简略信息，详细信息只能点击简略信息进行查看
    public List<BriefArticleVO> getAllBrief(Integer userId) {
        List<BriefArticleVO> res = briefArticleDAO.selectAll(userId);
        return res;
    }

    @Override
    public List<BriefArticleVO> getByUserName(DetailInfoDTO data) {
        List<BriefArticleVO> res = briefArticleDAO.selectByUserName(data);
        return res;
    }

    @Override
    // 查询某个用户所有博客
    public List<BriefArticleVO> getBriefByUser(Integer userId) {
        List<BriefArticleVO> res = briefArticleDAO.selectByUser(userId);
        return res;
    }

    @Override
    // 根据标题模糊查询
    public List<BriefArticleVO> getBriefByTitle(ArticleSelectDTO data) {
        List<BriefArticleVO> res = briefArticleDAO.selectByTitle(data);
        return res;
    }

    @Override
    public List<BriefArticleVO> getByTitleLike(DetailInfoDTO data) {
        List<BriefArticleVO> res = briefArticleDAO.getByTitleLike(data);
        return res;
    }

    @Override
    public List<BriefArticleVO> getByTitleCollect(DetailInfoDTO data) {
        List<BriefArticleVO> res = briefArticleDAO.getByTitleCollect(data);
        return res;
    }

    @Override
    // 显示回收站的博客
    public List<BriefArticleVO> getDeleted(Integer userId) {
        List<BriefArticleVO> res = briefArticleDAO.selectDeleted(userId);
        return res;
    }

    @Override
    // 查询出用户点赞的所有博客
    public List<BriefArticleVO> getLikeByUser(Integer userId) {
        List<BriefArticleVO> res = briefArticleDAO.selectLikeByUser(userId);
        return res;
    }

    @Override
    // 查询出用户点赞的所有博客
    public List<BriefArticleVO> getCollectByUser(Integer userId) {
        List<BriefArticleVO> res = briefArticleDAO.selectCollectByUser(userId);
        return res;
    }

    @Override
    public DetailArticleVO getUpdateDetail(Integer articleId) {
        DetailArticleVO res = briefArticleDAO.selectUpdateDetail(articleId);
        return res;
    }

    @Override
    // 点击简略信息查看详细信息，传过来博客id以及用户ID，查出来所有信息
    // 获取详细信息同时获取评论，便于前端展示。
    public AllArticleVO getAllDetail(Integer userId, Integer articleId) {
        BriefArticleVO brief = briefArticleDAO.selectByArticleId(userId, articleId);
        String content = detailArticleDAO.getById(articleId);
        List<CommentVO> comments = commentService.getByArticle(userId, articleId);
        AllArticleVO res = new AllArticleVO();
        BeanUtils.copyProperties(brief, res);
        res.setContent(content);
        res.setComments(comments);
        return res;
    }

    @Override
    @Transactional
    // 插入的时候给完整的信息，分成简略信息和详细信息，分别插入，有事务控制
    // 注意：由于修改了DetailArticle的变量名，导致需要手动赋值
    public void insert(ArticleInsertDTO data) {
        BriefArticle briefArticle = new BriefArticle();
        DetailArticle detailArticle = new DetailArticle();
        BeanUtils.copyProperties(data, briefArticle);
        BeanUtils.copyProperties(data, detailArticle);
        detailArticle.setVariousId(data.getUserId());
        briefArticleDAO.insert(briefArticle);
        detailArticleDAO.insert(detailArticle);
    }

    @Override
    @Transactional
    // 改变详细信息，包含标题（简略信息）和具体内容（详细信息）
    // 使用事务，分别更新。需要手动赋值，手动赋值时间
    public void changeDetail(ArticleUpdateDTO data) {
        DetailArticle detailArticle = new DetailArticle(data.getArticleId(), data.getContent());
        DetailInfoDTO briefArticle = new DetailInfoDTO(data.getArticleId(), data.getTitle(), LocalDateTime.now());
        briefArticleDAO.changeInfo(briefArticle);
        detailArticleDAO.change(detailArticle);
    }

    @Override
    @Transactional
    // 点赞、收藏和评论数量增加，是一个事务，数量变化同时关系表也随之改变
    // 注意：由于修改之后属性名大多数不相同，需要显式构造对象
    // 不能用beanutils赋值
    public void addNum(Relation data) {
        ChangeNumDTO changeNumDTO = new ChangeNumDTO(data.getVariousId(), data.getNewCount(), data.getType());
        briefArticleDAO.changeNum(changeNumDTO);
        relationDAO.insert(data);
    }

    @Override
    @Transactional
    // 点赞、收藏和评论数量减少
    public void subNum(Relation data) {
        ChangeNumDTO changeNumDTO = new ChangeNumDTO(data.getVariousId(), data.getNewCount(), data.getType());
        briefArticleDAO.changeNum(changeNumDTO);
        relationDAO.delete(data);
    }

    @Override
    // 普通删除就是隐藏对应博客，便于后续恢复
    public void hide(Integer articleId) {
        briefArticleDAO.hide(articleId);
    }

    @Override
    public void recover(Integer articleId) {
        briefArticleDAO.recover(articleId);
    }

    @Override
    @Transactional
    // 删除某一篇博客，删除点赞，保留收藏和评论，用户点击时提示文章已被删除
    // 注意：简略信息和详细信息都要删除
    public void delete(Integer articleId) {
        briefArticleDAO.delete(articleId);
        detailArticleDAO.delete(articleId);
        relationDAO.deleteArticle(articleId);
    }

    @Override
    @Transactional
    // 删除某一个用户的所有博客，同时删除下面的点赞关系，保留收藏和评论
    public void deleteByUser(Integer userId) {
        List<Integer> list = briefArticleDAO.selectIdByUser(userId);
        // list不为空，有文章再调用删除，否则SQL语句报错
        if (list != null && list.size() != 0) {
            relationDAO.deleteAllArticle(list);
        }
        briefArticleDAO.deleteAll(userId);
        detailArticleDAO.deleteAll(userId);
    }

}
